home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / aztecnos.arc / PATHNAME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-16  |  2.9 KB  |  120 lines

  1. #include "global.h"
  2.  
  3. static void crunch();
  4.  
  5. /* Given a working directory and an arbitrary pathname, resolve them into
  6.  * an absolute pathname. Memory is allocated for the result, which
  7.  * the caller must free
  8.  */
  9. char *
  10. pathname(cd,path)
  11. char *cd;    /* Current working directory */
  12. char *path;    /* Pathname argument */
  13. {
  14.     register char *buf,*cp;
  15.     char *cdtmp,*pathtmp;
  16.  
  17.     if(cd == NULLCHAR || path == NULLCHAR)
  18.         return NULLCHAR;
  19. #ifdef    MSDOS
  20.     /* Make temporary copies of cd and path
  21.      * with all \'s translated to /'s
  22.     */
  23.     pathtmp = strdup(path);
  24.     path = pathtmp;
  25.     if((cp = path) != NULLCHAR){
  26.         while((cp = strchr(cp,'\\')) != NULLCHAR)
  27.             *cp = '/';
  28.     }
  29.     cdtmp = strdup(cd);
  30.     cd = cdtmp;
  31.     if((cp = cd) != NULLCHAR){
  32.         while((cp = strchr(cp,'\\')) != NULLCHAR)
  33.             *cp = '/';
  34.     }
  35. #endif
  36.     /* Strip any leading white space on args */
  37.     while(*cd == ' ' || *cd == '\t')
  38.         cd++;
  39.     while(*path == ' ' || *path == '\t')
  40.         path++;
  41.  
  42.     /* Allocate and initialize output buffer; user must free */
  43.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10);    /* fudge factor */
  44.     if(buf == NULLCHAR)
  45.         return NULLCHAR;
  46.     buf[0] = '\0';
  47.  
  48.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  49.     if(path[0] != '/')
  50.         crunch(buf,cd);
  51.  
  52.     crunch(buf,path);
  53.  
  54.     /* Special case: null final path means the root directory */
  55.     if(buf[0] == '\0'){
  56.         buf[0] = '/';
  57.         buf[1] = '\0';
  58.     }
  59.  
  60. #ifdef    MSDOS
  61.     /* Translate all /'s back to \'s and free temp copies of args */
  62.     if((cp = buf) != NULLCHAR){
  63.         while((cp = strchr(cp,'/')) != NULLCHAR)
  64.             *cp = '\\';
  65.     }
  66.     free(cdtmp);
  67.     free(pathtmp);
  68. #endif
  69.     return buf;
  70. }
  71.  
  72. /* Process a path name string, starting with and adding to
  73.  * the existing buffer
  74.  */
  75. static void
  76. crunch(buf,path)
  77. char *buf;
  78. register char *path;
  79. {
  80.     register char *cp;
  81.     
  82.  
  83.     cp = buf + strlen(buf);    /* Start write at end of current buffer */
  84.     
  85.     /* Now start crunching the pathname argument */
  86.     for(;;){
  87.         /* Strip leading /'s; one will be written later */
  88.         while(*path == '/')
  89.             path++;
  90.         if(*path == '\0')
  91.             break;        /* no more, all done */
  92.         /* Look for parent directory references, either at the end
  93.          * of the path or imbedded in it
  94.          */
  95.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  96.             /* Hop up a level */
  97.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  98.                 cp = buf;    /* Don't back up beyond root */
  99.             *cp = '\0';        /* In case there's another .. */
  100.             path += 2;        /* Skip ".." */
  101.             while(*path == '/')    /* Skip one or more slashes */
  102.                 path++;
  103.         /* Look for current directory references, either at the end
  104.          * of the path or imbedded in it
  105.          */
  106.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  107.             /* "no op" */
  108.             path++;            /* Skip "." */
  109.             while(*path == '/')    /* Skip one or more slashes */
  110.                 path++;
  111.         } else {
  112.             /* Ordinary name, copy up to next '/' or end of path */
  113.             *cp++ = '/';
  114.             while(*path != '/' && *path != '\0')
  115.                 *cp++ = *path++;
  116.         }
  117.     }
  118.     *cp++ = '\0';
  119. }
  120.